#define _CRT_SECURE_NO_WARNINGS 1
#include "string.h"

namespace zzzyh
{

	const size_t string::npos = -1;
	void string::reserve(size_t n) {
		cout << "reserve:" << n << endl;
		if (n <= _capacity) {
			return;
		}
		char* tmp = new char[n + 1];
		strcpy(tmp, _str);
		delete[] _str;
		_str = tmp;
		_capacity = n;
	}

	void string::push_buck(char c)
	{
		if (_size == _capacity)
		{
			reserve(_capacity ==0?4:_capacity * 2);
		}
		char* e = end();
		char* ed = e + 1;
		*ed = '\0';
		*e = c;
		_size++;
	}

	string& string::operator+=(char c) {
		push_buck(c);
		return *this;
	}

	void string::append(const char* c)
	{
		size_t len = strlen(c);
		if (len+_size > _capacity)
		{
			//reserve(len + _size);
			reserve(len + _size>2*_capacity?len+_size:2*_capacity);
		}
		/*const char* tmp = c;
		while (*tmp != '\0') {
			push_buck(*tmp);
			tmp++;
		}*/
		strcpy(_str + _size, c);
		_size += len;
	}

	void string::insert(size_t pos, char c) {
		assert(pos <= _size);
		if (pos == _size) {
			push_buck(c);
			return;
		}
		if (_size + 1 > _capacity) {
			reserve(1 + _size > 2 * _capacity ? 1 + _size : 2 * _capacity);
		}
		memmove(_str + pos, _str + pos-1, strlen(_str + pos-1)+1);
		_str[pos-1] = c;
	}

	void string::insert(size_t pos, const char* c){
		assert(pos <= _size);
		if (pos == _size) {
			append(c);
			return;
		}
		size_t len = strlen(c);
		if (_size + len > _capacity) {
			reserve(len + _size > 2 * _capacity ? len + _size : 2 * _capacity);
		}
		memmove(_str + (pos + len-1), _str + pos-1, strlen(_str + pos-1)+1);
		memmove(_str + (pos - 1), c, len);
		_size += len;
		/*for (size_t i = 0; i < len; i++)
		{
			_str[pos - 1 + i] = c[i];
		}*/
	}

	void string::erase(size_t pos, size_t len)
	{
		assert(pos < _size);
		int leni = strlen(_str + pos);
		if (len >= leni) {
			_size -= leni;
			_str[pos] = '\0';
			return;
		}
		memmove(_str + pos, _str + pos + len, strlen(_str + pos + len) + 1);
		_size -= len;
	}
	size_t string::find(const char c,int pos) {
		assert(pos < _size);
		for (size_t i = pos; i < _size; i++)
		{
			if (_str[i] == c) {
				return i;
			}
		}
		return -1;
	}
	size_t string::find(const char* c, int pos) {
		assert(pos < _size);
		const char * tmp = strstr(_str+pos, c);
		if (tmp == nullptr) {
			return -1;
		}
		return tmp - _str;
	}


	string string::substr(size_t pos, size_t len)
	{
		assert(pos < _size);
		size_t i = len;
		int y = pos;
		string ret;
		while (y<_size && i > 0)
		{
			ret.push_buck(_str[y]);
			y++;
			i--;
		}
		return ret;
	}

	

	

}